/****************************************************
 * 													*
 * 					BanzaiP2P						*
 * 													*
 * Versione: 0.1.1									*
 * Autore: D'Annessa Marco							*
 * File: http.c										*
 ****************************************************/


#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "http.h"


///////////////////////// Request ///////////////////////////////////

void http_rqst_msg_init(struct http_rqst_msg* msg, char *hops, char *TTL)
{
	
	////////// Request Line //////////
	msg->rqst_line = NULL;
	
	////////// Request //////////
	strcpy(msg->request.method, "");
	strcpy(msg->request.uri, "");
	strcpy(msg->request.version, http_version);
	msg->request.method_code = -1;
		
	////////// General Header //////////
	strcpy(msg->gen_header.date, "");
	strcpy(msg->gen_header.pragma, "");

	////////// Request Header //////////
	strcpy(msg->rqst_header.auth, "");
	strcpy(msg->rqst_header.from, "");
	strcpy(msg->rqst_header.mod_since, "");
	strcpy(msg->rqst_header.referer, "");
	strcpy(msg->rqst_header.user_agent, "");
	
	////////// Entity Header //////////
	strcpy(msg->ent_header.allow, "");
	strcpy(msg->ent_header.cont_enc, "");
	strcpy(msg->ent_header.cont_len, "");
//	msg->ent_header.cont_len = NULL;
	strcpy(msg->ent_header.cont_type, "");
	strcpy(msg->ent_header.expires, "");
	strcpy(msg->ent_header.last_modified, "");
	
	strcpy(msg->ent_header.hops, hops);
	strcpy(msg->ent_header.TTL, TTL);

	////////// Entity //////////
	msg->entity = NULL;

}

int http_send_rqst(int sd, struct http_rqst_msg* msg, struct http_rspn_msg* rspn)
{

	int   ent_len    = 0;
	int   msg_len 	 = 0;
	char* msg_string = NULL;
		
	msg_string = (char *)malloc(4096);
	
	strcpy(msg_string, msg->request.method);
	strcat(msg_string, " ");
	strcat(msg_string, msg->request.uri);
	strcat(msg_string, " ");
	strcat(msg_string, http_version);
	
	strcat(msg_string, "\r\n");
	
	////////// General Header //////////
	//if(msg->gen_header.date != NULL)
	if( strcmp(msg->gen_header.date, "") != 0)
	{
		strcat(msg_string, http_gen_header_string[HTTP_STR_GEN_HEAD_DATE]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->gen_header.date);
		strcat(msg_string, "\r\n");
	}

	//if(msg->gen_header.pragma != NULL)
	if( strcmp(msg->gen_header.pragma, "") != 0)
	{
		strcat(msg_string, http_gen_header_string[HTTP_STR_GEN_HEAD_PRAGMA]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->gen_header.pragma);
		strcat(msg_string, "\r\n");
	}

	
	////////// Request Header //////////
	//if(msg->rqst_header.auth != NULL)
	if( strcmp(msg->rqst_header.auth, "") != 0)
	{
		strcat(msg_string, http_rqst_header_string[HTTP_STR_RQST_HEAD_AUTH]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rqst_header.auth);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rqst_header.from != NULL)
	if( strcmp(msg->rqst_header.from, "") != 0)
	{
		strcat(msg_string, http_rqst_header_string[HTTP_STR_RQST_HEAD_FROM]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rqst_header.from);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rqst_header.mod_since != NULL)
	if( strcmp(msg->rqst_header.mod_since, "") != 0)
	{
		strcat(msg_string, http_rqst_header_string[HTTP_STR_RQST_HEAD_MOD_SINCE]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rqst_header.mod_since);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rqst_header.referer != NULL)
	if( strcmp(msg->rqst_header.referer, "") != 0)
	{
		strcat(msg_string, http_rqst_header_string[HTTP_STR_RQST_HEAD_REFERER]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rqst_header.referer);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rqst_header.user_agent != NULL)
	if( strcmp(msg->rqst_header.user_agent, "") != 0)
	{
		strcat(msg_string, http_rqst_header_string[HTTP_STR_RQST_HEAD_USER_AGENT]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rqst_header.user_agent);
		strcat(msg_string, "\r\n");
	}


	////////// Entity Header //////////
	//if(msg->ent_header.allow != NULL)
	if( strcmp(msg->ent_header.allow, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_ALLOW]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.allow);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.cont_enc != NULL)
	if( strcmp(msg->ent_header.cont_enc, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_ENC]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_enc);
		strcat(msg_string, "\r\n");
	}

	if(msg->ent_header.cont_len != NULL)
	{
		ent_len = atoi(msg->ent_header.cont_len);
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_LEN]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_len);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.cont_type != NULL)
	if( strcmp(msg->ent_header.cont_type, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_TYPE]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_type);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.expires != NULL)
	if( strcmp(msg->ent_header.expires, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_EXPIRES]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.expires);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.last_modified != NULL)
	if( strcmp(msg->ent_header.last_modified, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_LAST_MOD]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.last_modified);
		strcat(msg_string, "\r\n");
	}
	
	//if(msg->ent_header.hops != NULL)
	if( strcmp(msg->ent_header.hops, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_HOPS]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.hops);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.TTL != NULL)
	if( strcmp(msg->ent_header.TTL, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_TTL]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.TTL);
		strcat(msg_string, "\r\n");
	}

//	if(msg->ent_header.id != NULL)
//	{
//		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_ID]);
//		strcat(msg_string, ": ");
//		strcat(msg_string, msg->ent_header.id);
//	}

	strcat(msg_string, "\r\n");

	msg_len = strlen(msg_string);
	
	send(sd, msg_string, msg_len, 0);
	
	if( (ent_len > 0) && (msg->entity != NULL)){
		send(sd, msg->entity, ent_len, 0);
	}
	
	
	http_recv_rspn(sd, rspn);
	
	free(msg_string);
	
	return 0;

}

int http_recv_rqst(int sd, struct http_rqst_msg* msg)
{
	
	unsigned int bytes_read;
	char buff[1024];
	int i = 0;
	
	while(1)
	{
		i = recv(sd, &buff[0], sizeof(char), 0);
		
		//printf("%c", buff[0]);

		if(i == -1)
			return i;
		else if(i > 0)
			break;
			
	}
	
	for(i = 1, bytes_read = 1; ; i++)
	{
		
		if( recv(sd, &buff[i], sizeof(char), 0) == -1){
			//TODO: Error management
			return -1;
		}

		bytes_read++;
		
		if(buff[i] == '\r'){

			i++;
			recv(sd, &buff[i], sizeof(char), 0);

			bytes_read++;

			if(buff[i] == '\n'){

				buff[i+1] = '\0';
				
				msg->rqst_line = (char *)malloc(bytes_read + 1);
			
				strcpy(msg->rqst_line, buff);

				break;
			
			}
			
			
		}
	
	}
	
	http_parse_rqst_line(&msg->request, msg->rqst_line);
	//printf("\nParsed rq line\n");
	
	http_method_code_get( &(msg->request));
	//printf("\nParsed method code\n");

	for(i = 0, bytes_read = 0; ; i++)
	{
		
		if( recv(sd, &buff[i], sizeof(char), 0) == -1){
			//TODO: Error management
			return -1;
		}

		bytes_read++;
		
		if(buff[i] == '\r'){

			i++;
			recv(sd, &buff[i], sizeof(char), 0);
			bytes_read++;

			if(buff[i] == '\n'){

				buff[i+1] = '\0';
				
				if(i == 1){
					break;
				}

				http_parse_rqst_opt(msg, buff);
				
				i = -1;
				bytes_read = 0;
				
			}
			
			
		}
	
	}

	//printf("\nParsed options\n");

	////////// Entity //////////
	int entity_len = 0;
	
	if(msg->ent_header.cont_len != NULL){
		entity_len = atoi(msg->ent_header.cont_len);
	}

	if(entity_len > 0){
		
		if(msg->entity != NULL){
			free(msg->entity);
		}
		
		msg->entity = (char *)malloc(entity_len);
			
		recv(sd, msg->entity, entity_len, 0);
	
	}

	//printf("\nParsed entity\n");

	return 0;

}

int http_parse_rqst_line(struct http_rqst* rqst, char *rqst_line)
{
	
	char *rq_line;
	rq_line = (char *)malloc(strlen(rqst_line)+1);
	strcpy(rq_line, rqst_line);

	strcpy(rqst->method, strtok(rq_line , " "));
	strcpy(rqst->uri, strtok(NULL , " "));
	strcpy(rqst->version, strtok(NULL , http_CRLF));
	
	free(rq_line);
	
	return 0;
}

int http_parse_rqst_opt(struct http_rqst_msg* msg, char *rqst_opt_line)
{
	//TODO: return x+HTTP_STR_ID
	//TODO: gestione Invalid options
	char *rq_line;
	char *temp;
	rq_line = (char *)malloc(strlen(rqst_opt_line)+1);
	strcpy(rq_line, rqst_opt_line);


	temp = strtok(rq_line , ":");

	////////// General Header //////////
	if(strcmp(rq_line, http_gen_header_string[HTTP_STR_GEN_HEAD_DATE]) == 0)
	{
		strcpy(msg->gen_header.date, strtok(NULL , " \r\n"));
		
		return HTTP_STR_GEN_HEAD_DATE;
	}

	if(strcmp(rq_line, http_gen_header_string[HTTP_STR_GEN_HEAD_PRAGMA]) == 0)
	{
		strcpy(msg->gen_header.pragma, strtok(NULL , " \r\n"));
		
		return HTTP_STR_GEN_HEAD_PRAGMA;
	}

	
	////////// Request Header //////////
	if(strcmp(rq_line, http_rqst_header_string[HTTP_STR_RQST_HEAD_AUTH]) == 0)
	{
		strcpy(msg->rqst_header.auth, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_AUTH;
	}

	if(strcmp(rq_line, http_rqst_header_string[HTTP_STR_RQST_HEAD_FROM]) == 0)
	{
		strcpy(msg->rqst_header.from, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_FROM;
	}
	
	if(strcmp(rq_line, http_rqst_header_string[HTTP_STR_RQST_HEAD_MOD_SINCE]) == 0)
	{
		strcpy(msg->rqst_header.mod_since, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_MOD_SINCE;	
	}
	
	if(strcmp(rq_line, http_rqst_header_string[HTTP_STR_RQST_HEAD_REFERER]) == 0)
	{
		strcpy(msg->rqst_header.referer, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_REFERER;	
	}

	if(strcmp(rq_line, http_rqst_header_string[HTTP_STR_RQST_HEAD_USER_AGENT]) == 0)
	{
		strcpy(msg->rqst_header.user_agent, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_USER_AGENT;	
	}
		
	////////// Entity Header //////////
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_ALLOW]) == 0)
	{
		strcpy(msg->ent_header.allow, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_ALLOW;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_ENC]) == 0)
	{
		strcpy(msg->ent_header.cont_enc, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_CONT_ENC;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_LEN]) == 0)
	{
		strcpy(msg->ent_header.cont_len, strtok(NULL , " \r\n"));
		//msg->ent_header.cont_len = strtok(NULL , " \r\n");
		
		return HTTP_STR_ENT_HEAD_CONT_LEN;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_TYPE]) == 0)
	{
		strcpy(msg->ent_header.cont_type, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_CONT_TYPE;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_EXPIRES]) == 0)
	{
		strcpy(msg->ent_header.expires, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_EXPIRES;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_LAST_MOD]) == 0)
	{
		strcpy(msg->ent_header.last_modified, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_LAST_MOD;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_HOPS]) == 0)
	{
		strcpy(msg->ent_header.hops, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_HOPS;
	}
	
	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_TTL]) == 0)
	{
		strcpy(msg->ent_header.TTL, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_TTL;
	}

	if(strcmp(rq_line, http_ent_header_string[HTTP_STR_ENT_HEAD_ID]) == 0)
	{
		//msg->ent_header.id = strtok(NULL , " \r\n");
		
		return HTTP_STR_ENT_HEAD_ID;
	}
	
	
	return -1;

}

///////////////////////// Response ///////////////////////////////////

void http_rspn_msg_init(struct http_rspn_msg* msg, char *hops, char *TTL)
{
	
	////////// Request Line //////////
	msg->status_line = NULL;
	
	////////// Response //////////
	strcpy(msg->response.version, "");
	strcpy(msg->response.code, "");
	strcpy(msg->response.reason, "");

	////////// General Header //////////
	strcpy(msg->gen_header.date, "");
	strcpy(msg->gen_header.pragma, "");

	////////// Response Header //////////
	strcpy(msg->rspn_header.location, "");
	strcpy(msg->rspn_header.server, "");
	strcpy(msg->rspn_header.www_auth, "");
	
	////////// Entity Header //////////
	strcpy(msg->ent_header.allow, "");
	strcpy(msg->ent_header.cont_enc, "");
	strcpy(msg->ent_header.cont_len, "");
	//msg->ent_header.cont_len = NULL;
	strcpy(msg->ent_header.cont_type, "");
	strcpy(msg->ent_header.expires, "");
	strcpy(msg->ent_header.last_modified, "");
	
	strcpy(msg->ent_header.hops, hops);
	strcpy(msg->ent_header.TTL, TTL);

	////////// Entity //////////
	msg->entity = NULL;

}

int http_send_rspn(int sd, struct http_rspn_msg* msg)
{

	int   ent_len    = 0;
	int   msg_len 	 = 0;
	char* msg_string = NULL;
		
	msg_string = (char *)malloc(4096);
	
	strcpy(msg_string, http_version);
	strcat(msg_string, " ");
	strcat(msg_string, msg->response.code);
	strcat(msg_string, " ");
	strcat(msg_string, msg->response.reason);
	
	strcat(msg_string, "\r\n");
	
	////////// General Header //////////
	//if(msg->gen_header.date != NULL)
	if( strcmp(msg->gen_header.date, "") != 0)
	{
		strcat(msg_string, http_gen_header_string[HTTP_STR_GEN_HEAD_DATE]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->gen_header.date);
		strcat(msg_string, "\r\n");
	}

	//if(msg->gen_header.pragma != NULL)
	if( strcmp(msg->gen_header.pragma, "") != 0)
	{
		strcat(msg_string, http_gen_header_string[HTTP_STR_GEN_HEAD_PRAGMA]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->gen_header.pragma);
		strcat(msg_string, "\r\n");
	}

	
	////////// Response Header //////////
	//if(msg->rspn_header.location != NULL)
	if( strcmp(msg->rspn_header.location, "") != 0)
	{
		strcat(msg_string, http_rspn_header_string[HTTP_STR_RSPN_HEAD_LOCATION]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rspn_header.location);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rspn_header.server != NULL)
	if( strcmp(msg->rspn_header.server, "") != 0)
	{
		strcat(msg_string, http_rspn_header_string[HTTP_STR_RSPN_HEAD_SERVER]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rspn_header.server);
		strcat(msg_string, "\r\n");
	}

	//if(msg->rspn_header.www_auth != NULL)
	if( strcmp(msg->rspn_header.www_auth, "") != 0)
	{
		strcat(msg_string, http_rspn_header_string[HTTP_STR_RSPN_HEAD_WWWAUTH]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->rspn_header.www_auth);
		strcat(msg_string, "\r\n");
	}


	////////// Entity Header //////////
	//if(msg->ent_header.allow != NULL)
	if( strcmp(msg->ent_header.allow, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_ALLOW]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.allow);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.cont_enc != NULL)
	if( strcmp(msg->ent_header.cont_enc, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_ENC]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_enc);
		strcat(msg_string, "\r\n");
	}

	if(msg->ent_header.cont_len != NULL)
	{
		ent_len = atoi(msg->ent_header.cont_len);
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_LEN]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_len);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.cont_type != NULL)
	if( strcmp(msg->ent_header.cont_type, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_TYPE]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.cont_type);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.expires != NULL)
	if( strcmp(msg->ent_header.expires, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_EXPIRES]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.expires);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.last_modified != NULL)
	if( strcmp(msg->ent_header.last_modified, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_LAST_MOD]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.last_modified);
		strcat(msg_string, "\r\n");
	}
	
	//if(msg->ent_header.hops != NULL)
	if( strcmp(msg->ent_header.hops, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_HOPS]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.hops);
		strcat(msg_string, "\r\n");
	}

	//if(msg->ent_header.TTL != NULL)
	if( strcmp(msg->ent_header.TTL, "") != 0)
	{
		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_TTL]);
		strcat(msg_string, ": ");
		strcat(msg_string, msg->ent_header.TTL);
		strcat(msg_string, "\r\n");
	}

//	if(msg->ent_header.id != NULL)
//	{
//		strcat(msg_string, http_ent_header_string[HTTP_STR_ENT_HEAD_ID]);
//		strcat(msg_string, ": ");
//		strcat(msg_string, msg->ent_header.id);
//	}
	
	strcat(msg_string, "\r\n");

	msg_len = strlen(msg_string);
	
	send(sd, msg_string, msg_len, 0);
	
	if( (ent_len > 0) && (msg->entity != NULL)){
		send(sd, msg->entity, ent_len, 0);
	}
printf("\n -HTTP- msglen = %d\n",ent_len);	

	free(msg_string);
	
	return 0;

}

int http_recv_rspn(int sd, struct http_rspn_msg* msg)
{
	
	unsigned int bytes_read;
	char buff[1024];
	int i = 0;
	
	while(1)
	{
		i = recv(sd, &buff[0], sizeof(char), 0);
		
		//printf("%c", buff[0]);
		
		if(i == -1)
			return i;
		else if(i > 0)
			break;
			
	}
	
	for(i = 1, bytes_read = 1; ; i++)
	{
		
		if( recv(sd, &buff[i], sizeof(char), 0) == -1){
			//TODO: Error management
			return -1;
		}
		
		bytes_read++;
		
		if(buff[i] == '\r'){

			i++;
			recv(sd, &buff[i], sizeof(char), 0);
			bytes_read++;

			if(buff[i] == '\n'){

				buff[i+1] = '\0';
			
				msg->status_line = (char *)malloc(bytes_read + 1);
			
				strcpy(msg->status_line, buff);

				break;
			
			}
			
			
		}
	
	}

	http_parse_rspn_line(&msg->response, msg->status_line);
	
	for(i = 0, bytes_read = 0; ; i++)
	{
		
		if( recv(sd, &buff[i], sizeof(char), 0) == -1){
			//TODO: Error management
			return -1;
		}

		bytes_read++;
		
		if(buff[i] == '\r'){

			i++;
			recv(sd, &buff[i], sizeof(char), 0);
			bytes_read++;

			if(buff[i] == '\n'){

				buff[i+1] = '\0';
				
				if(i == 1){
					break;
				}
				
				http_parse_rspn_opt(msg, buff);//perchè sbrocca?
				
				i = -1;
				bytes_read = 0;
				
			}
			
			
		}
	
	}
	

	////////// Entity //////////
	int entity_len = 0;
	
	if(msg->ent_header.cont_len != NULL){
		entity_len = atoi(msg->ent_header.cont_len);
	}

	if(entity_len > 0){
		
		if(msg->entity != NULL){
			free(msg->entity);
		}
		
		msg->entity = (char *)malloc(entity_len);
printf("\n -HTTP- msglen = %d\n",entity_len);			
		int r = recv(sd, msg->entity, entity_len, 0);
printf("\n -HTTP- RECV = %d\n",r);				
	
	}


	return 0;

}

int http_parse_rspn_line(struct http_rspn* rspn, char *rspn_line)
{
	
	char *rs_line;
	rs_line = (char *)malloc(strlen(rspn_line)+1);
	strcpy(rs_line, rspn_line);

	strcpy(rspn->version, strtok(rs_line , " "));
	strcpy(rspn->code, strtok(NULL , " "));
	strcpy(rspn->reason, strtok(NULL , http_CRLF)); 
	
	free(rs_line);
		
	return 0;

}

int http_parse_rspn_opt(struct http_rspn_msg* msg, char *rspn_opt_line)
{
	//TODO: return x+HTTP_STR_ID
	char *rs_line;
	char *temp;
	rs_line = (char *)malloc(strlen(rspn_opt_line)+1);
	strcpy(rs_line, rspn_opt_line);


	temp = strtok(rs_line , ":");

	////////// General Header //////////
	if(strcmp(rs_line, http_gen_header_string[HTTP_STR_GEN_HEAD_DATE]) == 0)
	{
		strcpy(msg->gen_header.date, strtok(NULL , " \r\n"));
		
		return HTTP_STR_GEN_HEAD_DATE;
	}

	if(strcmp(rs_line, http_gen_header_string[HTTP_STR_GEN_HEAD_PRAGMA]) == 0)
	{
		strcpy(msg->gen_header.pragma, strtok(NULL , " \r\n"));
		
		return HTTP_STR_GEN_HEAD_PRAGMA;
	}

	
	////////// Request Header //////////
	if(strcmp(rs_line, http_rspn_header_string[HTTP_STR_RSPN_HEAD_LOCATION]) == 0)
	{
		strcpy(msg->rspn_header.location, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_AUTH;
	}

	if(strcmp(rs_line, http_rspn_header_string[HTTP_STR_RSPN_HEAD_SERVER]) == 0)
	{
		strcpy(msg->rspn_header.server, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_FROM;
	}
	
	if(strcmp(rs_line, http_rspn_header_string[HTTP_STR_RSPN_HEAD_WWWAUTH]) == 0)
	{
		strcpy(msg->rspn_header.www_auth, strtok(NULL , " \r\n"));
		
		return HTTP_STR_RQST_HEAD_MOD_SINCE;	
	}

		
	////////// Entity Header //////////
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_ALLOW]) == 0)
	{
		strcpy(msg->ent_header.allow, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_ALLOW;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_ENC]) == 0)
	{
		strcpy(msg->ent_header.cont_enc, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_CONT_ENC;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_LEN]) == 0)
	{
		//msg->ent_header.cont_len = strtok(NULL , " \r\n");
		strcpy(msg->ent_header.cont_len, strtok(NULL , " \r\n"));
		return HTTP_STR_ENT_HEAD_CONT_LEN;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_CONT_TYPE]) == 0)
	{
		strcpy(msg->ent_header.cont_type, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_CONT_TYPE;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_EXPIRES]) == 0)
	{
		strcpy(msg->ent_header.expires, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_EXPIRES;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_LAST_MOD]) == 0)
	{
		strcpy(msg->ent_header.last_modified, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_LAST_MOD;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_HOPS]) == 0)
	{
		strcpy(msg->ent_header.hops, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_HOPS;
	}
	
	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_TTL]) == 0)
	{
		strcpy(msg->ent_header.TTL, strtok(NULL , " \r\n"));
		
		return HTTP_STR_ENT_HEAD_TTL;
	}

	if(strcmp(rs_line, http_ent_header_string[HTTP_STR_ENT_HEAD_ID]) == 0)
	{
		//msg->ent_header.id = strtok(NULL , " \r\n");
		
		return HTTP_STR_ENT_HEAD_ID;
	}
	
	
	return -1;

}


short int http_method_code_get(struct http_rqst* rqst)
{

	////////// Request //////////
	if( strcmp(rqst->method, http_rqst_method_string[HTTP_STR_RQST_METH_GET]) == 0)
	{
		return (rqst->method_code = HTTP_METHOD_CODE_GET);
	}

	if( strcmp(rqst->method, http_rqst_method_string[HTTP_STR_RQST_METH_HEAD]) == 0)
	{
		return (rqst->method_code = HTTP_METHOD_CODE_HEAD);
	}

	if( strcmp(rqst->method, http_rqst_method_string[HTTP_STR_RQST_METH_POST]) == 0 )
	{
		return (rqst->method_code = HTTP_METHOD_CODE_POST);
	}

	if( strcmp(rqst->method, http_rqst_method_string[HTTP_STR_RQST_METH_THEP2P]) == 0 )
	{

		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_CONNECT]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_CONNECT);
		}

		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_DISCONNECT]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_DISCONNECT);
		}
	
		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_PING]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_PING);
		}
	
		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_PONG]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_PONG);
		}
	
		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_QUERY]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_QUERY);
		}
	
		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_QUERYHIT]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_QUERYHIT);
		}
	
		if( strcmp(rqst->uri, http_rqst_thep2p_string[HTTP_STR_RQST_THEP2P_PEERFILELIST]) == 0 )
		{
			return (rqst->method_code = HTTP_METHOD_CODE_PEERFILELIST);
		}

	}
	
	return -1;

}
